namespace Arcane.Source.Combat
{
    public enum ModifierType
    {
        Attack, Magic, Hurt, MagicalHurt, Charge, EnergyLoss,
    }

    public static class ModifierTypeExt
    {
        public static ModifierType GetHurt(this DamageType damageType) => damageType switch
        {
            DamageType.Common => ModifierType.Hurt,
            DamageType.Magical => ModifierType.MagicalHurt,
            _ => ModifierType.MagicalHurt,
        };

        public static ModifierType GetAttack(this DamageType damageType) => damageType switch
        {
            DamageType.Common => ModifierType.Attack,
            DamageType.Magical => ModifierType.Magic,
            _ => ModifierType.Magic,
        };

        public static bool TryParseModifierType(this string type, out ModifierType ty)
        {
            switch (type)
            {
                case "attack":
                    ty = ModifierType.Attack;
                    return true;
                
                case "magic":
                    ty = ModifierType.Magic;
                    return true;

                case "hurt":
                    ty = ModifierType.Hurt;
                    return true;
                
                case "magical_hurt":
                    ty = ModifierType.MagicalHurt;
                    return true;
                
                case "charge":
                    ty = ModifierType.Charge;
                    return true;
                
                case "energy_loss":
                    ty = ModifierType.EnergyLoss;
                    return true;

                default:
                    ty = default;
                    return false;
            }
        }
    }

    public enum ModifierOp
    {
        Mul, Add, FinalMul, FinalAdd
    }

    public static class ModifierOpExt
    {
        public static bool TryParseModifierOp(this string type, out ModifierOp op)
        {
            switch (type)
            {
                case "add":
                    op = ModifierOp.Add;
                    return true;
                    
                case "mul":
                    op = ModifierOp.Mul;
                    return true;

                case "final_add":
                    op = ModifierOp.FinalAdd;
                    return true;

                case "final_mul":
                    op = ModifierOp.FinalMul;
                    return true;

                default:
                    op = default;
                    return false;
            }
        }
    }

    public class Modifier
    {
        public ModifierType type;
        public ModifierOp op;
        public float value;

        public static bool IsMul(Modifier m) => m.op == ModifierOp.Mul;
        public static bool IsAdd(Modifier m) => m.op == ModifierOp.Add;
        public static bool IsFinalMul(Modifier m) => m.op == ModifierOp.FinalMul;
        public static bool IsFinalAdd(Modifier m) => m.op == ModifierOp.FinalAdd;
        public static float Accumulate(float accu, Modifier modifier)
        {
            return accu + modifier.value;
        }
    }
}